package cn.broadmax.boot.util;

import jexx.util.CollectionUtil;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Utils {

    /**
     * 找到左边差集
     * @param left 左集合
     * @param right 右集合
     * @param <T> 泛型
     * @return 左边差集
     */
    public static <T> Set<T> findLeftDiff(final Collection<T> left, final Collection<T> right){
        if(CollectionUtil.isEmpty(left)){
            return new HashSet<>();
        }
        Set<T> set = new HashSet<>(left);
        if(right != null){
            set.removeAll(right);
        }
        return set;
    }

    /**
     * 通过转换获取同一类型元素后并比较，找到左边的差集
     * @param left 左集合
     * @param leftTransform 左集合转换
     * @param right 右集合
     * @param rightTransform 右集合转换
     * @param <M> 左集合泛型
     * @param <N> 右集合泛型
     * @param <T> 同一元素类型
     * @return 返回左边差集
     */
    public static <M,N,T> Set<M> findLeftDiff(final Collection<M> left, Function<M,T> leftTransform, final Collection<N> right, Function<N,T> rightTransform){
        if(CollectionUtil.isEmpty(left)){
            return new HashSet<>();
        }
        Set<M> set = new HashSet<>(left);
        if(CollectionUtil.isNotEmpty(right)){
            List<T> rightIds = right.stream().map(rightTransform).collect(Collectors.toList());
            set = set.stream().filter(s -> !rightIds.contains(leftTransform.apply(s))).collect(Collectors.toSet());
        }
        return set;
    }

    /**
     * 通过转换获取同一类型元素后并比较，找到左边的差集
     * @param left 左集合
     * @param right 右集合
     * @param transform 统一集合转换
     * @param <M> 集合泛型
     * @param <T> 同一元素类型
     * @return 返回左边差集
     */
    public static <M,T> Set<M> findLeftDiff(final Collection<M> left, final Collection<M> right, Function<M,T> transform){
        return findLeftDiff(left, transform, right, transform);
    }

    /**
     * 通过转换获取同一类型元素后并比较，找到左边相同
     * @param left 左集合
     * @param leftTransform 左集合转换
     * @param right 右集合
     * @param rightTransform 右集合转换
     * @param <M> 左集合泛型
     * @param <N> 右集合泛型
     * @param <T> 同一元素类型
     * @return 返回左边差集
     */
    public static <M,N,T> Set<M> findLeftSame(final Collection<M> left, Function<M,T> leftTransform, final Collection<N> right, Function<N,T> rightTransform){
        if(CollectionUtil.isEmpty(left)){
            return new HashSet<>();
        }
        Set<M> set = new HashSet<>(left);
        if(CollectionUtil.isNotEmpty(right)){
            List<T> rightIds = right.stream().map(rightTransform).collect(Collectors.toList());
            set = set.stream().filter(s -> rightIds.contains(leftTransform.apply(s))).collect(Collectors.toSet());
        }
        return set;
    }

    /**
     * 通过转换获取同一类型元素后并比较，找到左边相同
     * @param left 左集合
     * @param right 右集合
     * @param transform 统一集合转换
     * @param <M> 集合泛型
     * @param <T> 同一元素类型
     * @return 返回左边差集
     */
    public static <M,T> Set<M> findLeftSame(final Collection<M> left, final Collection<M> right, Function<M,T> transform){
        return findLeftSame(left, transform, right, transform);
    }

}
